<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>类和原型</title>
</head>

<body>
  <script>
    // 这个工厂函数返回一个新范围的对象
    function range(from, to) {
      // 使用Object.create()创建一个对象，继承下面定义的原型对象。这个原型对象保存为这个函数的一个属性，为所有范围对象r定义共享方法（行为）
      let r = Object.create(range.methods)
      // 保存新范围对象的起点和终点（状态）
      // 这些属性不是继承，而是当前对象独有的属性
      // console.log(r);
      r.from = from
      r.to = to

      console.log(new.target);
      // 返回新对象
      return r
    }

    // 这个原型对象定义由所有对象继承的方法
    range.methods = {
      // 如果x在范围内则返回true，否则返回false
      // 这个方法适用于文本、日期和数值范围
      includes(x) { return this.from <= x && x <= this.to },
      // 这个生成器函数让这个类的实例可迭代
      // 注意：只适用于数值范围
      *[Symbol.iterator]() {
        for (let x = Math.ceil(this.from); x <= this.to; x++)yield x;
      },
      // 返回范围的字符串表示
      toString() { return "(" + this.from + "..." + this.to + ")" }
    }

    let a = range(1.5, 3)
    console.log(a);
    console.log(a.includes(3));
    console.log(a.toString());
    console.log([...a]);
    console.log(range.methods.isPrototypeOf(a));//range.methods是r的原型对象
  </script>
</body>

</html>